#include "CCSlotTransform.h"
#include "CCSpineGlobal.h"
#include "CCSkeletalSprite.h"
#include "CCSpineSprite.h"

NS_CC_BEGIN

CCSlotTransform::CCSlotTransform() {
}

CCSlotTransform::CCSlotTransform(CCSlot *slot) :
m_slot(slot) {
}

CCSlotTransform::~CCSlotTransform() {
	for (auto it:m_skfList) {
		if (it.attachmentName) {
			free((void *) it.attachmentName);
		}
	}
}

CCSlotTransform *CCSlotTransform::create(CCSlot *slot) {
	CCSlotTransform *bt = new CCSlotTransform(slot);
	return (CCSlotTransform *) bt->autorelease();
}

void CCSlotTransform::addSkinKeyFrame(const SkinKeyFrame &kf) {
	m_skfList.push_back(kf);
}

void CCSlotTransform::addColorKeyFrame(const ColorKeyFrame &kf) {
	m_ckfList.push_back(kf);
}

void CCSlotTransform::populateFrame(float time, float deltaTime) {
	// process skin frame
	// set time to current time
	m_currentSkin.time = time;
	m_currentSkin.valid = true;

	// if empty, just set to zero
	// if not, found key frame, do interpolation if needed
	if (m_skfList.empty()) {
		m_currentSkin.valid = false;
	} else {
		SkinKeyFrameList::iterator iter = m_skfList.begin();
		for (; iter != m_skfList.end(); iter++) {
			SkinKeyFrame &kf = *iter;
//			if (time < kf.time) {
//				if (iter == m_skfList.begin()) {
//					m_currentSkin.attachmentName = kf.attachmentName;
//				} else {
//					SkinKeyFrame &prevKf = *(iter - 1);
//					float percent = getInterpolationTime(prevKf.time, kf.time, time, prevKf.interpolator);
//					if (percent >= 1) {
//						m_currentSkin.attachmentName = kf.attachmentName;
//					}
//					else {
//						m_currentSkin.attachmentName = prevKf.attachmentName;
//					}
//				}
//				break;
//			} else
			if (time >= kf.time && (time - deltaTime) <= kf.time) {
				m_currentSkin.attachmentName = kf.attachmentName;
				break;
			}
		}

		// if exceed last one
		if (iter == m_skfList.end()) {
			m_currentSkin.attachmentName = m_skfList.rbegin()->attachmentName;
		}
	}

	// process color frame
	// set time to current time
	m_currentColor.time = time;
	m_currentColor.valid = true;

	// if empty, just set to zero
	// if not, found key frame, do interpolation if needed
	if (m_ckfList.empty()) {
		m_currentColor.valid = false;
	} else {
		ColorKeyFrameList::iterator iter = m_ckfList.begin();
		for (; iter != m_ckfList.end(); iter++) {
			ColorKeyFrame &kf = *iter;
			if (time < kf.time) {
				if (iter == m_ckfList.begin()) {
					m_currentColor.color = kf.color;
				} else {
					ColorKeyFrame &prevKf = *(iter - 1);
					float percent = getInterpolationTime(prevKf.time, kf.time, time, prevKf.interpolator);

					m_currentColor.color.r = percent * (kf.color.r - prevKf.color.r) + prevKf.color.r;
					m_currentColor.color.g = percent * (kf.color.g - prevKf.color.g) + prevKf.color.g;
					m_currentColor.color.b = percent * (kf.color.b - prevKf.color.b) + prevKf.color.b;
					m_currentColor.color.a = percent * (kf.color.a - prevKf.color.a) + prevKf.color.a;
				}
				break;
			} else if (time == kf.time) {
				m_currentColor.color = kf.color;
				break;
			}
		}

		// if exceed last one
		if (iter == m_ckfList.end()) {
			m_currentColor.color = m_ckfList.rbegin()->color;
		}
	}
}

void CCSlotTransform::applyTo(CCSkeletalSprite *owner, float alpha) {

	//don't use alpha

	// get state of this owner
	CCSlot::State &state = m_slot->getState(owner);
	//CCSlot::State& original = slot->getOriginalState();

	// check sprite
	/*
	if(!sprite)
		return false;*/

	// set skin texture
	if (m_currentSkin.valid && !m_slot->hasFlag(CCSlot::FIXED_ATTACHMENT)) {
		state.activeAttachmentName = m_currentSkin.attachmentName;
	}

	// set color
	if (m_currentColor.valid && !m_slot->hasFlag(CCSlot::FIXED_COLOR)) {
		state.color = m_currentColor.color;
		/*
		state.color.r+=(m_currentColor.color.r-original.color.r)*alpha;
		state.color.g+=(m_currentColor.color.g-original.color.g)*alpha;
		state.color.b+=(m_currentColor.color.b-original.color.b)*alpha;
		state.color.a+=(m_currentColor.color.a-original.color.a)*alpha;*/
	}
}

NS_CC_END